const AXIOS = require("axios").default;
const FormData = require("form-data");
const setCookieParser = require("set-cookie-parser");
const CommonAxerrH = require("../tool/CommonAxerrHandler");
class GiteeClient {
  constructor() {
    /**
     * @type {Array<{name:String,value:String}>}
     */
    this.THE_cookie_stores = [];
    this.THE_csrfToken = "";
    this.axios = AXIOS.create({
      headers: {
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
        "Accept-Encoding": "gzip, deflate, br",
        "Accept-Language": "en-US,en;q=0.9,zh;q=0.8,zh-CN;q=0.7",
        "Connection": "keep-alive",
        "Sec-Fetch-Dest": "document",
        "Sec-Fetch-Mode": "navigate",
        "Sec-Fetch-Site": "same-origin",
        "Sec-Fetch-User": "?1",
        "Upgrade-Insecure-Requests": "1",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4115.5 Safari/537.36 OPR/70.0.3707.0 (Edition developer)"
      },
      validateStatus: s => s == 200
    });
    this.parseSetCookieInResp = (axresp) => {
      if (axresp.headers && axresp.headers['set-cookie']) {
        let parsed = setCookieParser.parse(axresp.headers['set-cookie']);
        for (let v of parsed) {
          let findi = this.THE_cookie_stores.findIndex(e => e.name == v.name);
          if (findi >= 0) {
            this.THE_cookie_stores[findi].value = v.value;
          } else {
            this.THE_cookie_stores.push({
              name: v.name,
              value: v.value
            })
          }
        }
      }
    }
  }

  get cookies_as_header() {
    return this.THE_cookie_stores.map(e => `${e.name}=${e.value}`).join("; ")
  }

  /**
   * @returns {Promise<{ok:Boolean,msg:String}>}
   */
  ["INIT_visitGitee.com"]() {
    return new Promise(resolve => {
      this.axios.get(`https://gitee.com`, {
        headers: {
          cookie: this.cookies_as_header
        }
      }).then(axresp => {
        this.parseSetCookieInResp(axresp);
        if (!(axresp.headers['content-type'] && axresp.headers['content-type'].includes("text/html"))) {
          return resolve({
            ok: false,
            msg: `not text/html:${axresp.headers}`
          })
        }
        /**@type {string} */
        let html = axresp.data;
        let matched = axresp.data.match(/\<meta content=\"([^"]*)\" name="csrf-token/);
        if (matched && matched.length == 2) {
          this.THE_csrfToken = matched[1];
          return resolve({
            ok: true,
            msg: "ok"
          })
        } else {
          return resolve({
            ok: false,
            msg: "cant find csrf-token by RegExp"
          })
        }
      }).catch(axerr => {
        CommonAxerrH(resolve)(axerr)
      })
    })
  }

  /**
   * @returns {Promise<{ok:Boolean,msg:String,data:{
   * list:Array<{
   * name:String,
   * sort_id:Number
   * }>
   * }}>}
   * @param {String} project_path 形如"user/prj1" 
   */
  getWikiPageList(project_path) {
    return new Promise(resolve => {
      this.axios.get(`https://gitee.com/${project_path}/wikis/pages/wikis?info_id=0`, {
        headers: {
          'X-CSRF-Token': this.THE_csrfToken,
          cookie:this.cookies_as_header
        }
      })
        .then(axresp => {
          this.parseSetCookieInResp(axresp);
          if (axresp.data['code'] == 200) {
            return resolve({
              ok: true,
              msg: "ok",
              data: {
                list: axresp.data['msg'].map(e => {
                  return {
                    name: e.name,
                    sort_id: e.sort_id
                  }
                })
              }
            })
          }
          throw axresp.data;
        }).catch(axerr => {
          CommonAxerrH(resolve)(axerr)
        })
    })
  }

  /**
   * @returns {Promise<{ok:Boolean,msg:String,
   * data:{
   * content:String,
   * contentHtml:String,
   * sort_id:Number,
   * title:String
   * }}>}
   * @param {String} project_path 
   * @param {Number} sort_id 
   */
  getWikiContent(project_path, sort_id) {
    return new Promise(resolve => {
      this.axios.get(`https://gitee.com/${project_path}/wikis/pages/wiki`, {
        headers: {
          'X-CSRF-Token': this.THE_csrfToken,
          cookie:this.cookies_as_header
        },
        params: {
          sort_id: sort_id
        }
      }).then(axresp => {
        if (axresp.data['code'] == 200) {
          return resolve({
            ok: true,
            msg: "ok",
            data: {
              content: axresp.data['wiki']['content'],
              contentHtml: axresp.data['wiki']['content_html'],
              sort_id: axresp.data['wiki']['sort_id'],
              title: axresp.data['wiki']['title'],
            }
          })
        }
        throw axresp.data;
      }).catch(axerr => {
        CommonAxerrH(resolve)(axerr)
      })
    })
  }


}



/**
 * @returns {Promise<{ok:Boolean,msg:String,data:{
 * gitee:GiteeClient
 * }}>}
 * @param {String} giteeSessionN 
 */
function GetGiteeBySession(giteeSessionN) {
  return new Promise(resolve => {
    let gitee = new GiteeClient();
    gitee.THE_cookie_stores = [{
      name: "gitee-session-n",
      value: giteeSessionN
    }];
    gitee['INIT_visitGitee.com']().then(o => {
      if (o.ok) {
        return resolve({
          ok: true,
          msg: "ok",
          data: {
            gitee: gitee
          }
        })
      } else {
        return resolve({
          ok: false,
          msg: o.msg
        })
      }
    })
  })
}


module.exports = {
  GetGiteeBySession
}